#-*- coding = utf-8 -*-
from datetime import datetime
from datetime import timedelta
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By

# 抢购失败最大次数
max_retry_count = 30

# 自动抢票类（京东）
class JDong:

    def __init__(self, seckill_time_str=None, password=None):
        # 抢购时间
        self.seckill_time = datetime.strptime(seckill_time_str, '%Y-%m-%d %H:%M:%S')
        # 支付密码
        self.password = password
        # 驱动
        self.driver = None

    # 登录京东
    def login(self, login_url="https://jd.com"):
        if login_url:
            self.driver = webdriver.Edge()
        else:
            raise Exception("Please input the login url.")

        # 打开首页
        self.driver.get(login_url)
        # 全屏
        self.driver.maximize_window()

        while True:
            try:
                # 尝试获取点击登录超链接
                login_lists = self.driver.find_elements(By.XPATH, '//a[@class="link-login"]')
                if login_lists[0]:
                    login_lists[0].click()
                    print("点击登录...")
                    break
            except Exception as e:
                pass

        while True:
            try:
                # 尝试获取点击扫码登录
                qr_lists = self.driver.find_elements(By.XPATH, '//div[@class="login-tab login-tab-l"]/a')
                if qr_lists[0]:
                    qr_lists[0].click()
                    print("点击扫码登录...")
                    break
            except Exception as e:
                pass

        # 等待登录
        while True:
            try:
                # 尝试获取登录成功页面的元素，找到了表示已经登录成功。
                if self.driver.find_elements(By.XPATH, '//a[@class="nickname"]'):
                    print("登陆成功")
                    # 进入购物车
                    self.driver.get("https://cart.jd.com/cart_index")
                    # 结束循环
                    break
            except Exception as e:
                pass

    # 等待抢购
    def keep_wait(self):
        print("等待到点抢购...")
        while True:
            # 获取当前时间
            current_time = datetime.now()
            # 如果距离抢购时间大于3分钟，则每分钟刷新一次界面，防止登录超时。
            if (self.seckill_time - current_time).seconds > 180:
                # 进入购物车
                self.driver.get("https://cart.jd.com/cart_index")
                print("每分钟刷新一次界面，防止登录超时...")
                sleep(60)
            else:
                print("抢购时间点将近，停止自动刷新，准备进入抢购阶段...")
                # 抢购时间将近，结束等待抢购
                break

    # 支付页面
    def pay(self):
        sleep(5)
        while True:
            try:
                # 等待框架加载完毕
                ifr_lists = self.driver.find_elements(By.XPATH, '//div[@id="baseMode"]')
                if ifr_lists[0]:
                    print("准备支付")
                    break
            except Exception as e:
                pass

        sleep(3)
        while True:
            try:
                # 等待密码框加载完毕
                password_lists = self.driver.find_elements(By.XPATH, '//input[@class="validate-short-input"]')
                if password_lists[0]:
                    # 输入密码
                    password_lists[0].send_keys(self.password)
                    print("密码输入完成")
                    break
            except Exception as e:
                pass

        sleep(3)
        while True:
            try:
                # 等待确认付款按钮加载完成,并付款
                enable_lists = self.driver.find_elements(By.XPATH, '//div[@class="btn"]//div[@class="base-button pointer-g"]')
                if enable_lists[0]:
                    enable_lists[0].click()
                    print("确定付款")
                    break
            except Exception as e:
                pass

    # 全选商品
    def select_all(self, one=False):
        while True:
            try:
                # 获取全选框
                select_all_lists = self.driver.find_elements(By.XPATH, '//input[@class="jdcheckbox"]')
                if select_all_lists[0]:
                    # 获取全选框的值
                    # 因为京东会记录上一次选中的情况，所以需要判断是否选中，如果未选中，才去自动选中。
                    is_check = select_all_lists[0].get_attribute('clstag')
                    if is_check == "pageclick|keycount|Shopcart_CheckAll|0":
                        # 点击全选
                        select_all_lists[0].click()
                        print("已经选中全部商品！！！")
                    break
                if one:
                    break
            except Exception as e:
                pass

    # 抢购的入口函数
    def sec_kill(self):
        print("此次抢购时间：{}".format(datetime.strftime(self.seckill_time, "%Y-%m-%d %H:%M:%S")))
        # 调用登录函数
        self.login()
        # 调用等待抢购函数
        self.keep_wait()

        # 记录提交状态
        submit_success = False
        # 重试抢购次数
        retry_count = 0

        print("当前未选状态，自动选择全部商品")
        self.select_all()

        while True:
            # 获取当前时间，提前1秒开始抢购
            now = datetime.now() + timedelta(seconds=1)
            if now >= self.seckill_time:
                # 正式抢购时，再次检查是否选中了商品
                # 因为京东秒杀时间之前，是不能够选择商品的，所以在正式抢购时，需要再次判断是否选中
                self.select_all(one=True)
                print(f"开始抢购, 尝试次数： {str(retry_count + 1)}")
            else:
                print('\r倒计时：',(self.seckill_time-now).total_seconds(),'秒 ',end='')
                # 睡眠一段时间,防止cpu一直工作
                sleep(0.1)
                continue

            try:
                # 等待结算按钮可以被点击
                while True:
                    try:
                        common_lists = self.driver.find_elements(By.XPATH, '//a[@class="common-submit-btn"]')
                        if common_lists[0]:
                            common_lists[0].click()
                            print("已经点击结算按钮...")
                            break
                    except Exception as e:
                        pass

                # 等待跳转到提交订单按钮可以被点击
                while True:
                    try:
                        # 需要输入支付密码才能提交订单
                        try:
                            pw_lists = self.driver.find_elements(By.XPATH, '//input[@class="quark-pw-result-input"]')
                            if pw_lists[0]:
                                # 输入密码
                                pw_lists[0].send_keys(self.password)
                                print("密码输入完成")
                        except Exception as e:
                            pass

                        checkout_lists = self.driver.find_elements(By.XPATH, '//button[@class="checkout-submit"]')
                        if checkout_lists[0]:
                            checkout_lists[0].click()
                            print("已经点击提交订单按钮...")
                            break
                    except Exception as e:
                        pass

                # 等待跳转到立即支付按钮可以被点击
                while True:
                    try:
                        payt_lists = self.driver.find_elements(By.XPATH, '//div[@class="pay-button-wrapper"]//div[@class="base-button pointer-g"]')
                        if payt_lists[0]:
                            payt_lists[0].click()
                            print("已经点击立即支付按钮...")
                            break
                    except Exception as e:
                        pass

                # 记录提交状态
                submit_success = True
                break
            except Exception as e:
                retry_count += 1
                if retry_count > max_retry_count:
                    print("重试抢购次数达到上限，放弃重试...")
                    break
        
        # 提交成功,准备支付
        if submit_success:
            if self.password:
                self.pay()
            else:
                print("订单已提交")
                self.driver.get("https://order.jd.com/center/list.action?s=1")
            print("抢购已完成，5分钟后关闭浏览器...")
            sleep(300)
            self.driver.quit()

